package ro.msg.quiz.view;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import ro.msg.quiz.controller.Controller;
import ro.msg.quiz.repository.MultipleChoiceQ;
import ro.msg.quiz.repository.Question;
import ro.msg.quiz.repository.SingleChoiceQ;
import ro.msg.quiz.repository.TextQ;

/**
 * Create the dialog.
 * 
 * @author Adorjan
 */
public class AddNewQuestion extends JDialog {
	private static AddNewQuestion instance = null;
	private static int NOT_ASSIGNED = -1;
	private final JPanel buttonPane = new JPanel();
	private final JButton btnBack = new JButton("Back");
	private final JButton nextButton = new JButton("Next");
	private final JButton cancelButton = new JButton("Cancel");
	private final JButton btnFinish = new JButton("Finish");
	private AddQuestionStepOnePanel addQuestionStepOnePanel;
	private AddQuestionStepTwoPanel addQuestionStepTwoPanel;
	private Controller ctrl;
	private final int maxAnswerNo = 20;
	private int questionId;

	/**
	 * The dialog's constructor
	 * 
	 * @author Adorjan
	 */
	private AddNewQuestion(Controller controller) {
		this.questionId = NOT_ASSIGNED;
		setTitle("Add new question");
		init(controller);
	}

	/**
	 * Constructor with a questionId
	 * 
	 * @param controller
	 * @param question
	 */
	private AddNewQuestion(Controller controller, Integer question) {
		this.questionId = question;
		setTitle("Edit question");
		init(controller);
	}

	/**
	 * Initializes the dialog
	 * 
	 * @param controller
	 */
	private void init(Controller controller) {
		this.ctrl = controller;
		setResizable(false);
		setBounds(100, 100, 450, 300);
		getContentPane().setLayout(null);

		addQuestionStepOnePanel = new AddQuestionStepOnePanel(ctrl, questionId);
		addQuestionStepTwoPanel = new AddQuestionStepTwoPanel(0, 0);
		addQuestionStepTwoPanel.setVisible(false);
		addQuestionStepOnePanel.setBounds(0, 0, 434, 229);
		getContentPane().add(addQuestionStepOnePanel);

		buttonPane.setBounds(0, 228, 434, 33);
		buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
		getContentPane().add(buttonPane);

		btnBack.setHorizontalAlignment(SwingConstants.LEFT);
		buttonPane.add(btnBack);
		btnBack.setVisible(false);

		/**
		 * Back button's action listener
		 */
		btnBack.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				addQuestionStepOnePanel.setVisible(true);
				getContentPane().remove(addQuestionStepTwoPanel);
				btnBack.setVisible(false);
				btnFinish.setVisible(false);
				nextButton.setVisible(true);
			}
		});

		/**
		 * Cancel button's action listener
		 */
		cancelButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				dispose();
			}
		});

		cancelButton.setActionCommand("Cancel");
		buttonPane.add(cancelButton);

		/**
		 * Finish button's action listener
		 */
		btnFinish.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				String text = addQuestionStepOnePanel.getTxtQuestion()
						.getText().toString();
				int qType = addQuestionStepOnePanel.getComboBox()
						.getSelectedIndex() + 1;

				ArrayList<String> options = new ArrayList<String>();
				for (JTextField field : addQuestionStepTwoPanel.getAnswerText()) {
					options.add(field.getText().toString());
				}

				int i = 0;
				if (questionId == NOT_ASSIGNED) {
					questionId = ctrl.getLastIdQuestionRepo() + 1;
				} else {
					// remove the old record
					ctrl.removeQuestion(questionId);
				}

				Question question = null;
				switch (qType) {
				case 1:
					int correctOption = 0;
					i = 0;
					for (JRadioButton radio : addQuestionStepTwoPanel
							.getAnswerRadio()) {
						if (radio.isSelected()) {
							correctOption = i;
							break;
						}
						i++;
					}
					question = new SingleChoiceQ(questionId, text, options,
							correctOption);
					break;
				case 2:
					ArrayList<Integer> correctOptions = new ArrayList<Integer>();
					i = 0;
					for (JCheckBox check : addQuestionStepTwoPanel
							.getAnswerCheck()) {
						if (check.isSelected()) {
							correctOptions.add(i);
						}
						i++;
					}
					question = new MultipleChoiceQ(questionId, text, i + 1,
							options, correctOptions);
					break;
				case 3:
					question = new TextQ(questionId, text, options.get(0));
					break;
				}
				ctrl.addQuestion(question);
				dispose();
			}
		});

		buttonPane.add(btnFinish);
		btnFinish.setVisible(false);

		/**
		 * Combobox's (on the first panel) action listener
		 */
		addQuestionStepOnePanel.getComboBox().addActionListener(
				new ActionListener() {

					@Override
					public void actionPerformed(ActionEvent arg0) {
						if (addQuestionStepOnePanel.getComboBox()
								.getSelectedIndex() == 2)
							nextButton.setEnabled(true);
						else
							nextButton.setEnabled(false);

					}
				});

		/**
		 * Textfield's (on the first panel) document listener
		 */
		addQuestionStepOnePanel.getTxtAnswerNo().getDocument()
				.addDocumentListener(new DocumentListener() {
					@Override
					public void changedUpdate(DocumentEvent e) {
						changed();
					}

					@Override
					public void removeUpdate(DocumentEvent e) {
						changed();
					}

					@Override
					public void insertUpdate(DocumentEvent e) {
						changed();
					}

					public void changed() {
						int qType = addQuestionStepOnePanel.getComboBox()
								.getSelectedIndex();
						// if single choice/multiple choice
						if (addQuestionStepOnePanel.getTxtAnswerNo().getText()
								.toString().equals("")
								&& qType < 2) {
							addQuestionStepOnePanel.getTxtAnswerNo()
									.setEnabled(true);
							nextButton.setEnabled(false);
						}
						// if text
						else if (qType == 2) {
							addQuestionStepOnePanel.getTxtAnswerNo()
									.setEnabled(false);
							nextButton.setEnabled(true);
						} else {
							nextButton.setEnabled(true);
						}

					}
				});

		// if an existing question was given
		if ((questionId != NOT_ASSIGNED)
				&& (ctrl.getFromQuestionList(questionId).getType() == 3))
			nextButton.setEnabled(true);
		else
			nextButton.setEnabled(false);

		/**
		 * Next button's action listener
		 */
		nextButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (addQuestionStepOnePanel.getTxtQuestion().getText()
						.toString().equals(""))
					JOptionPane.showMessageDialog(null,
							"Fill in the question text area!", "Oops!",
							JOptionPane.WARNING_MESSAGE);
				else {
					int qType = addQuestionStepOnePanel.getComboBox()
							.getSelectedIndex();
					int answerNo = 0;

					// single || multiple choice
					if (qType < 2) {
						try {
							answerNo = Integer.parseInt(addQuestionStepOnePanel
									.getTxtAnswerNo().getText().toString());
						} catch (NumberFormatException e) {
							System.err
									.println("Invalid number of answers - 0!");
						}
						if (answerNo > 0)
							if (answerNo <= 20)
								addQuestionStepTwoPanel = new AddQuestionStepTwoPanel(
										qType, answerNo);
							else {
								JOptionPane
										.showMessageDialog(
												null,
												"Maximum number of possible answers is "
														+ maxAnswerNo
														+ ". Number of answers is set to it.",
												"Oops!",
												JOptionPane.WARNING_MESSAGE);
								addQuestionStepTwoPanel = new AddQuestionStepTwoPanel(
										qType, maxAnswerNo);
							}
					}
					// text
					else if (qType == 2)
						addQuestionStepTwoPanel = new AddQuestionStepTwoPanel(
								qType, 1);

					addQuestionStepTwoPanel.setBounds(0, 0, 434, 229);
					getContentPane().add(addQuestionStepTwoPanel);
					addQuestionStepTwoPanel.setVisible(true);
					addQuestionStepOnePanel.setVisible(false);
					btnBack.setVisible(true);
					btnFinish.setVisible(true);
					nextButton.setVisible(false);

				}
			}
		});
		nextButton.setActionCommand("OK");
		buttonPane.add(nextButton);
		getRootPane().setDefaultButton(nextButton);

	}

	/**
	 * makes an instance of this class
	 * 
	 * @param controller
	 * @return
	 */
	public static AddNewQuestion getInstance(Controller controller) {
		if (instance == null) {
			instance = new AddNewQuestion(controller);
		}
		return instance;
	}

	/**
	 * makes an instance of this class with a given question's id
	 * 
	 * @param controller
	 * @return
	 */
	public static AddNewQuestion getInstance(Controller controller,
			Integer question) {
		if (instance == null) {
			instance = new AddNewQuestion(controller, question);
		}
		return instance;
	}

	/**
	 * resets the instance of this dialog
	 * 
	 * @param controller
	 */
	public static void reset() {
		instance = null;
	}
}
